#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2024-6-20 18:10
# @Author  : jiaoxianzhong
# @File    : mysql_db_help.py
# @Software: PyCharm
# python mysql 操作类

import pymysql
from dbutils.pooled_db import PooledDB
from config import config


class DBHelper:

    def __init__(self):
        """
        :param mincached:连接池中空闲连接的初始数量
        :param maxcached:连接池中空闲连接的最大数量
        :param maxshared:共享连接的最大数量
        :param maxconnections:创建连接池的最大数量
        :param blocking:超过最大连接数量时候的表现，为True等待连接数量下降，为false直接报错处理
        :param maxusage:单个连接的最大重复使用次数
        :param setsession:optional list of SQL commands that may serve to prepare
            the session, e.g. ["set datestyle to ...", "set time zone ..."]
        :param reset:how connections should be reset when returned to the pool
            (False or None to rollback transcations started with begin(),
            True to always issue a rollback for safety's sake)
        :param host:数据库ip地址
        :param port:数据库端口
        :param db:数据库名
        :param user:用户名
        :param passwd:密码
        :param charset:字符编码
        """
        mincached = 0
        maxcached = 0
        maxshared = 0
        maxconnections = 0
        blocking = True
        maxusage = 0
        setsession = None
        reset = True
        host = config.mysql_config["host"]
        port = config.mysql_config["port"]
        db = config.mysql_config["database"]
        user = config.mysql_config["user"]
        passwd = config.mysql_config["password"]
        charset = 'utf8mb4'
        try:
            self.__pool = PooledDB(pymysql,
                                   mincached, maxcached,
                                   maxshared, maxconnections, blocking,
                                   maxusage, setsession, reset,
                                   host=host, port=port, db=db,
                                   user=user, passwd=passwd,
                                   charset=charset,
                                   cursorclass=pymysql.cursors.DictCursor
                                   )
        except Exception as e:
            print(e)

    def get_conn(self):
        try:
            conn = self.__pool.connection()
            cursor = conn.cursor()
            return conn, cursor
        except Exception as e:
            print(e)

    @staticmethod
    def dispose(cursor, conn):
        cursor.close()
        conn.close()

    # 返回执行execute()方法后影响的行数
    def execute(self, sql):
        try:
            conn, cursor = self.get_conn()
            cursor.execute(sql)
            rowcount = cursor.rowcount
            return rowcount
        except Exception as e:
            print(e)

    # 删除并返回影响行数
    def delete(self, **kwargs):
        conn, cursor = self.get_conn()
        table = kwargs['table']

        where = kwargs['where']
        sql = 'DELETE FROM %s where %s' % (table, where)
        print(sql)
        rowcount = 0
        try:
            # 执行SQL语句
            cursor.execute(sql)
            # 提交到数据库执行
            conn.commit()
            # 影响的行数
            rowcount = cursor.rowcount
        except Exception as e:
            print(e)
            # 发生错误时回滚
            conn.rollback()
        return rowcount

    # 新增并返回新增ID
    def insert(self, **kwargs):
        conn, cursor = self.get_conn()
        table = kwargs['table']
        del kwargs['table']
        sql = 'insert into %s(' % table
        fields = ""
        values = ""
        for k, v in kwargs.items():
            fields += "%s," % k
            values += "'%s'," % v
        fields = fields.rstrip(',')
        values = values.rstrip(',')
        sql = sql + fields + ")values(" + values + ")"
        print(sql)
        res = 0
        try:
            # 执行SQL语句
            cursor.execute(sql)
            # 提交到数据库执行
            conn.commit()
            # 获取自增id
            res = cursor.lastrowid
        except Exception as e:
            print(e)
            # 发生错误时回滚
            conn.rollback()
        return res

    # 修改数据并返回影响的行数
    def update(self, **kwargs):
        conn, cursor = self.get_conn()
        table = kwargs['table']
        # del kwargs['table']
        kwargs.pop('table')
        where = kwargs['where']
        kwargs.pop('where')
        sql = 'update %s set ' % table
        for k, v in kwargs.items():
            sql += "%s='%s'," % (k, v)
        sql = sql.rstrip(',')
        sql += ' where %s' % where
        print(sql)
        rowcount = 0
        try:
            # 执行SQL语句
            cursor.execute(sql)
            # 提交到数据库执行
            conn.commit()
            # 影响的行数
            rowcount = cursor.rowcount
        except Exception as e:
            print(e)
            # 发生错误时回滚
            conn.rollback()
        return rowcount

    # 查-一条条数据
    def selectOne(self, **kwargs):
        conn, cursor = self.get_conn()
        table = kwargs['table']
        field = 'field' in kwargs and kwargs['field'] or '*'
        where = 'where' in kwargs and 'where ' + kwargs['where'] or ''
        order = 'order' in kwargs and 'order by ' + kwargs['order'] or ''
        sql = 'select %s from %s %s %s limit 1' % (field, table, where, order)
        print(sql)
        data = None
        try:
            # 执行SQL语句
            cursor.execute(sql)
            # 使用 fetchone() 方法获取单条数据.
            data = cursor.fetchone()
        except Exception as e:
            print(e)
            # 发生错误时回滚
            conn.rollback()
        return data

    # 查所有数据
    def selectAll(self, **kwargs):
        conn, cursor = self.get_conn()
        table = kwargs['table']
        field = 'field' in kwargs and kwargs['field'] or '*'
        where = 'where' in kwargs and 'where ' + kwargs['where'] or ''
        order = 'order' in kwargs and 'order by ' + kwargs['order'] or ''
        sql = 'select %s from %s %s %s ' % (field, table, where, order)
        print(sql)
        data = None
        try:
            # 执行SQL语句
            cursor.execute(sql)
            # 使用 fetchone() 方法获取单条数据.
            data = cursor.fetchall()
        except Exception as e:
            print(e)
            # 发生错误时回滚
            conn.rollback()
        return data
